%% Author: casey
%% Created: Mar 13, 2007
%% Description: TODO: Add desciption to dc_auth
-module(dc_auth).
-behavior(gen_event).

-include("dc_types.hrl").

%%
%% Include files
%%

%%
%% Exported Functions
%%
-export([init/1, handle_event/2, terminate/2]).

%%
%% API Functions
%%
init(Handle) ->
    {ok, Handle}.

handle_event(Cmd, Handle=#handle{socket=Socket,conn_info=ConnInfo}) ->
    io:fwrite("dc_auth: ~p~n", [Cmd]),
    case Cmd of
        {lock, Lock, _Pk} ->
            %%io:fwrite("$Key " ++ lock_to_key(Lock) ++ "|"),
            gen_tcp:send(Socket, "$Key " ++ lock_to_key(Lock) ++ "|"),
            gen_tcp:send(Socket, "$ValidateNick " ++ ConnInfo#conn_info.nick ++ "|"),
            {ok, Handle};
        get_pass ->
		    gen_tcp:send(Socket, "$MyPass " ++ ConnInfo#conn_info.password),
			{ok, Handle};
        hello ->
            gen_tcp:send(Socket, "$Version " ++ "1,0091|"),
            gen_tcp:send(Socket, "$MyINFO $ALL " ++
                                 ConnInfo#conn_info.nick ++ " <++ V:0.688,M:A,H:1/0/0,S:10>$" ++
                                 "$Cable3$\"\"$100000000000$|"),
			{ok, Handle};
        _ ->
			{ok, Handle}
    end.

terminate(_Args, _State) ->
    ok.

%%
%% Local Functions
%%

%% From dcpp.net/wiki
lock_to_key(Lock) ->
    [First | Tail] = Lock,
    {Key, _} = lists:mapfoldl(fun(Cur, Prev) -> {Cur bxor Prev, Cur} end, First, Tail),
    [Lock1, Lock2] = lists:nthtail(length(Lock) - 2, Lock), [Lock0 | _] = Lock,
    Key2 = [Lock0 bxor Lock1 bxor Lock2 bxor 5 | Key],
    Key3 = lists:map(fun(Val) -> <<Hi:4, Low:4>> = <<Val>>, <<Res>> = <<Low:4, Hi:4>>, Res end, Key2),
    Key4 = lists:foldl(fun(Val, AccIn) ->
        AccIn ++
        if
            Val ==   0 -> "/%DCN000%/";
            Val ==   5 -> "/%DCN005%/";
            Val ==  36 -> "/%DCN036%/";
            Val ==  96 -> "/%DCN096%/";
            Val == 124 -> "/%DCN124%/";
            Val == 126 -> "/%DCN126%/";
            true -> [Val]
       end
    end, [], Key3),
    Key4.

